﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using UtilZ.Dotnet.Ex.Attributes;
using UtilZ.Dotnet.Ex.Model;
using UtilZ.Dotnet.WindowsDesktopEx.Winform;

namespace WinFormApp
{
    public partial class FTestDataGridViewEx : Form, ICollectionOwner
    {
        public FTestDataGridViewEx()
        {
            InitializeComponent();
        }

        private DataGridView dataGridView1;
        private int _count = 0;
        private BindingCollection<DGVDataItem> _items;
        private void FTestDataGridViewEx_Load(object sender, EventArgs e)
        {
            bool dgvEx = true;
            this.dataGridView1 = this.CreateDataGridView(dgvEx);

            //方法四,数据对象中添加一个字段用于表示行号
            dataGridView1.CellPainting += DataGridViewEx1_CellPainting;//根据行数据条件不同背景色

            
            this._items = new BindingCollection<DGVDataItem>(this);

            for (int i = 0; i < 20000; i++)
            {
                this._items.Add(new DGVDataItem("张三", "内江", 23));
                this._items.Add(new DGVDataItem("李四", "资中", 28));
                this._items.Add(new DGVDataItem("王五", "东兴区", 32));
                this._items.Add(new DGVDataItem("陈六", "安岳", 19));
                this._items.Add(new DGVDataItem("吴七", "成都", 45));

                this._items.Add(new DGVDataItem("汤二", "都江堰", 36));
                this._items.Add(new DGVDataItem("刘一", "青城山", 17));
                this._items.Add(new DGVDataItem("刘一", "青城山", 67));
                this._items.Add(new DGVDataItem("刘一", "青城山", 55));
                this._items.Add(new DGVDataItem("刘一", "青城山", 66));
            }

            //dataGridView1.DataSource = _items.DataSource;
            //dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;


        }

        private DataGridView CreateDataGridView(bool dgvEx)
        {
            DataGridView dgv;            
            if (dgvEx)
            {
                dgv = new DataGridViewEx()
                {
                    MouseRightButtonChangeSelectedRow = false,
                };
            }
            else
            {
                dgv = new DataGridView();
                //设置行头宽度.行号4-6位数：70，3位数：60，1-2位数50
                //dgv.RowHeadersWidth = 70;

                //禁止用户拖动行头调整大小,适用于确定最大行数，不确定时禁止了可用会尴尬，
                //也可以选择在知道最大行数后再设置RowHeadersWidth值,单表数据记录数超过100万的概率想来不大,那样的话也该做其它优化设计了
                dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
                
                //方法一,可视区域有多少绘制多少，性能最好 15~767
                dgv.RowPostPaint += DataGridView1_RowPostPaint;

                //方法二,会嵌套循环，性能最差,4000~?
                //dgv.RowsAdded += DataGridView1_RowsAdded;
                //dgv.RowsRemoved += DataGridView1_RowsRemoved;

                //方法三 最简单，性能不如方法一,48~1445
                //dgv.RowStateChanged += DataGridView1_RowStateChanged;
            }

            dgv.AllowUserToResizeRows = false;
            dgv.AllowUserToAddRows = false;
            dgv.AllowUserToDeleteRows = false;
            dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dgv.MultiSelect = false;
            dgv.Name = "dgv";
            dgv.ReadOnly = true;
            dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgv.Dock = DockStyle.Fill;
            panel1.Controls.Add(dgv);

            return dgv;
        }

        private void DataGridView1_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
        {
            e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1);
            this._count++;
        }

        private void DataGridView1_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            for (int i = 0; i < e.RowCount && i < this.dataGridView1.Rows.Count; i++)
            {
                this._count++;
                dataGridView1.Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                dataGridView1.Rows[e.RowIndex + i].HeaderCell.Value = (e.RowIndex + i + 1).ToString();
            }

            for (int i = e.RowIndex + e.RowCount; i < this.dataGridView1.Rows.Count; i++)
            {
                this._count++;
                dataGridView1.Rows[i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                dataGridView1.Rows[i].HeaderCell.Value = (i + 1).ToString();
            }
        }

        private void DataGridView1_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            for (int i = 0; i < e.RowCount; i++)
            {
                this._count++;
                dataGridView1.Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                dataGridView1.Rows[e.RowIndex + i].HeaderCell.Value = (e.RowIndex + i + 1).ToString();
            }

            for (int i = e.RowIndex + e.RowCount; i < this.dataGridView1.Rows.Count; i++)
            {
                this._count++;
                dataGridView1.Rows[i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                dataGridView1.Rows[i].HeaderCell.Value = (i + 1).ToString();
            }
        }


        private readonly StringFormat _rowNumberTextFormat = new StringFormat()
        {
            // right alignment might actually make more sense for numbers
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Center
        };
        private void DataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            this._count++;
            var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, ((DataGridView)sender).RowHeadersWidth, e.RowBounds.Height);
            e.Graphics.DrawString((e.RowIndex + 1).ToString(), this.Font, SystemBrushes.ControlText, headerBounds, this._rowNumberTextFormat);
        }

        private void DataGridViewEx1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex < 0)
            {
                return;
            }

            if (this._items[e.RowIndex].Age < 20)
            {
                e.CellStyle.BackColor = Color.Green;
            }
            else if (this._items[e.RowIndex].Age < 30)
            {
                e.CellStyle.BackColor = Color.Red;
            }
            else if (this._items[e.RowIndex].Age < 40)
            {
                e.CellStyle.BackColor = Color.Goldenrod;
            }
            else if (this._items[e.RowIndex].Age < 50)
            {
                e.CellStyle.BackColor = Color.Gray;
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = _items.DataSource;
            dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }


        private void btnCount_Click(object sender, EventArgs e)
        {
            label1.Text = this._count.ToString();
            this._count = 0;
        }

        private readonly Random _random = new Random();
        private void btnRemove_Click(object sender, EventArgs e)
        {
            this._items.RemoveAt(this._random.Next(0, this._items.Count));
        }


        private class DGVDataItem
        {
            [DisplayNameEx("ID")]
            public int ID { get; set; }

            [DisplayNameEx("名称")]
            public string Name { get; set; }

            [DisplayNameEx("地址")]
            public string Addr { get; set; }

            [DisplayNameEx("年龄")]
            public int Age { get; set; }

            private static int _id = 1;
            public DGVDataItem(string name, string addr, int age)
            {
                this.ID = _id++;

                this.Name = name;
                this.Addr = addr;
                this.Age = age;
            }

        }

    }
}
